package com.czh.thread;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;

/**
 * 并发测试
 * 1. 守护线程(垃圾回收器): 将线程调用setDaemon(true)方法，例如: t1.setDaemon(true),在运行只要非守护线程都运行结束了,即使守护线程没执行完也会强制结束
 *
 * @author chenzhihua
 * @Date 2024/3/14
 */
public class ThreadTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
//        // 1. thread创建
//        ThreadC c = new ThreadC();
//        c.start();
//        //2.实现runnable创建
//        Thread a = new Thread(new ThreadA());
//        a.start();
//        //3.实现callable实现
//        FutureTask<Object> futureTask = new FutureTask<>(new ThreadB());
//        Thread thread = new Thread(futureTask);
//        thread.start();
//        System.out.println(futureTask.get());
//        System.out.println();
//        //4.线程池实现
//        ExecutorService executorService = Executors.newCachedThreadPool();
//        for (int i = 0; i < 10; i++) {
//            executorService.execute(new ThreadA());
//        }
//        executorService.shutdown();
        TwoPhaseTermination thread = new TwoPhaseTermination();
        thread.start();

        Thread.sleep(3500);

        thread.stop();

    }
}

class ThreadA implements Runnable {
    @Override
    public void run() {
        System.out.println("ThreadA===线程执行方法");
    }
}

class ThreadB implements Callable<Object> {
    @Override
    public Object call() throws Exception {
        System.out.println("ThreadB====线程执行方法");
        return "ThreadB";
    }
}

class ThreadC extends Thread {
    @Override
    public void run() {
        System.out.println("ThreadC====线程执行方法");
    }
}

// 两阶段终止
class TwoPhaseTermination {
    // 定义一个监控线程
    private Thread monitor;

    // 线程启动
    public void start() {
        monitor = new Thread(() -> {
            while (true) {
                Thread thread = Thread.currentThread();
                // 判断线程是否被打断，不会清除打断标记
                if (thread.isInterrupted()) {
                    System.out.println("线程被打断,料理后事");
                    break;
                }
                try {
                    Thread.sleep(1000);
                    System.out.println("执行监控");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    // 如果在睡眠状态下被打断则异常,打断标记变成false,重新设置打断标志
                    thread.interrupt();
                }
            }
        });
        monitor.start();
    }

    // 线程打断
    public void stop() {
        monitor.interrupt();
    }
}


// 烧水泡茶多线程实现(统筹规划)
class MoreThread {
    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            System.out.println("洗水壶用了一分钟");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("洗水壶完成");
            System.out.println("烧开水用了5分钟");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("烧开水完成");
        }, "t1");

        Thread t2 = new Thread(() -> {
            System.out.println("洗茶壶用了2分钟");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("泡茶杯用了1分钟");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("拿茶叶用了1分钟");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            // TODO 存在缺陷,只能t2进行泡茶
            try {
                t1.join();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("开始泡茶");
        }, "t2");
        t1.start();
        t2.start();
    }
}

